package com.geneticAlgorithm.wines;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;

public class CandidatesWines {
	// Holds our candidates of wines
    private ArrayList<Wine> candidates = new ArrayList<Wine>();
    // Cache
    private double fitness = 0;
    private int distance = 0;
    private final int AMOUNT = 999999999;
    
    // Constructs a blank candidate
    public CandidatesWines(){
        for (int i = 0; i < WinesManager.numberOfWines(); i++) {
        	candidates.add(null);
        }
    }
    
    public CandidatesWines(ArrayList<Wine> candidates){
        this.candidates = candidates;
    }

    // Creates a random individual
    public void generateIndividual() {
       
        for (int wineIndex = 0; wineIndex < WinesManager.numberOfWines(); wineIndex++) {
        	setWine(wineIndex, WinesManager.getWine(wineIndex));
        }
      
        Collections.shuffle(candidates);
    }

    // Gets a wine from the candidates
    public Wine getWine(int candidatePosition) {
        return (Wine)candidates.get(candidatePosition);
    }

    // Sets a wine in a certain position within candidate
    public void setWine(int candidatePosition, Wine wine) {
        candidates.set(candidatePosition, wine);
        // If the candidates been altered we need to reset the fitness and distance
        fitness = 0;
        distance = 0;
    }
    
    // Gets the candidates fitness
    public double getFitness() {
        if (fitness == 0) {
            fitness = 1/(double)getDistance();
        }
        return fitness;
    }
    
    // Gets the total distance of the candidate
    public int getDistance(){
        if (distance == 0) {
            int candidateDistance = 0;
          
            for (int wineIndex=0; wineIndex < candidatesSize(); wineIndex++) {
               
                Wine fromWine = getWine(wineIndex);
               
                Wine destinationWine;
                
                if(wineIndex+1 < candidatesSize()){
                	destinationWine = getWine(wineIndex+1);
                }
                else{
                	destinationWine = getWine(0);
                }
               
                candidateDistance += fromWine.distanceTo(destinationWine);
            }
            distance = candidateDistance;
        }
        return distance;
    }


    public int candidatesSize() {
        return candidates.size();
    }
    
   
    public boolean containsWine(Wine wine){
        return candidates.contains(wine);
    }
    
    @Override
    public String toString() {
        String geneString = "";
        Random randomGenerator = new Random();
        int randomInt = randomGenerator.nextInt(AMOUNT);
        
        for (int i = 0; i < candidatesSize(); i++) {
            geneString += getWine(i)+"";
            geneString += "\t\t Cantidad: "+randomInt;
            geneString += "\n\n";
            randomInt = randomGenerator.nextInt(randomInt);
        }
        return geneString;
    }
}
